﻿using System;
using System.Drawing;
using System.Windows.Forms;

namespace VS2048
{
    public partial class PlayBox : PaintBox
    {
        private int _cellWid = 66;
        private int _cellNumARow = 4;

        private Color _internalLineColor = Color.FromArgb(187, 173, 159);
        private Color _backcolor = Color.FromArgb(204, 193, 179);

        private PlayRuleController _playRuler = null;

        public int CellNumARow
        {
            get { return _cellNumARow; }
            set { _cellNumARow = value; }
        }

        public GameSummaryInfo CurGameSummaryInfo
        {
            get { return _playRuler.CurGameSummaryInfo; }
        }

        public Action<GameSummaryInfo> OnGameSummaryInfoChanged;

        public PlayBox()
        {
            InitializeComponent();
            Initialize();
        }

        private void Initialize()
        {
            //if (_playRuler == null)
            {
                _playRuler = new PlayRuleController(this, _cellNumARow, _cellNumARow);
                _playRuler.OnGameSummaryInfoChanged -= new Action<GameSummaryInfo>(RefreshGameInfo);
                _playRuler.OnGameSummaryInfoChanged += new Action<GameSummaryInfo>(RefreshGameInfo);
            }
        }

        private void RefreshGameInfo(GameSummaryInfo gsInfo)
        {
            if (OnGameSummaryInfoChanged != null)
                OnGameSummaryInfoChanged(gsInfo);
        }

        protected override void OnPaint(PaintEventArgs e)
        {
            base.OnPaint(e);
            this.BackColor = _backcolor;

            #region -= 画背景网格 =-
            using (Pen linePen = new Pen(_internalLineColor, 6))
            {
                int x = (this.Width - _cellNumARow * _cellWid) / 2;
                int y = (this.Height - _cellNumARow * _cellWid) / 2;

                e.Graphics.DrawRectangle(linePen, x, y, _cellNumARow * _cellWid, _cellNumARow * _cellWid);
               
                for (int i = 0; i < _cellNumARow; i++)
                {
                    for (int j = 0; j < _cellNumARow; j++)
                    {
                        e.Graphics.DrawLine(linePen, x + _cellWid * i, y + _cellWid * j, x + _cellWid * i, y + _cellWid * _cellNumARow);
                        e.Graphics.DrawLine(linePen, x + _cellWid * i, y + _cellWid * j, x + _cellWid * _cellNumARow, y + _cellWid * j);
                    }
                }
            }
            #endregion

            #region -= 画Cell =-
            if (_playRuler.Cells == null) return;
            for (int m = 0; m < _playRuler.Cells.GetLength(0); m++)
            {
                for (int n = 0; n < _playRuler.Cells.GetLength(1); n++)
                {
                    if (_playRuler.Cells[m, n] != null)
                    {
                        //System.Threading.Thread.Sleep(100);
                        _playRuler.Cells[m, n].Render(e.Graphics);
                    }
                }
            }
            #endregion

        }

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            Initialize();
            this.Invalidate();
        }

        protected override void OnKeyUp(KeyEventArgs e)
        {
            _playRuler.DoKeyUp(e.KeyValue);
            base.OnKeyUp(e);
        }

        public void UpdateCell(ICell cell)
        {
            if (cell != null)
            {
                int mx = (this.Width - _cellNumARow * _cellWid) / 2;
                int my = (this.Height - _cellNumARow * _cellWid) / 2;

                int realx = mx + cell.Coordinate.RowIndex * _cellWid;
                int realy = my + cell.Coordinate.ColIndex * _cellWid;

                cell.Left = realy + 3;
                cell.Top = realx + 3;
                cell.Width = _cellWid - 6;
                cell.Height = _cellWid - 6;
                cell.ParentWidth = _cellWid;//父容器边长，即网格正方形的边长
            }
            RefreshMe();
        }

        public delegate void ControlRefreshEvent();

        public void RefreshMe()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new ControlRefreshEvent(RefreshMe));
            }
            else { this.Refresh(); }
        }

        public void ResetGame()
        {
            _playRuler.ClearModel();
            RefreshMe();
        }
    }
}
